<?php
/**
 * 利用 MySQL 实现伪 PDO 
 *
 * @filesource _mysql.class.php
 * @package peck
 * @subpackage _db
 * @version $id: 0.3, utf8, Sun Dec 20 21:24:46 CST 2009
 * @author LD King <kldscs[at]gmail.com>
 * @copyright Copyleft (D.) 2007 - 2009 MiFunny China Inc.
 * @link http://mifunny.info/
 * @example 
 *   
 */
include_once '_sql_prepare.class.php';

class _mysql{
	/**
	 * @var int $query_count 本次连接所执行的SQL语句数目
	 */
	public $query_count = 0;
    private $mysql = null;

    /**
     * 初始化 MySQL
     *
     * @param array $policy
     */
    public function __construct($policy){
        if( empty($policy) ){
            throw new LogicException('('.__METHOD__.')Error: empty database policy array !');
        }else{
            //如何连接 MySQL Server
            if( empty($policy['unix_socket']) ){
                $server = $policy['host'];
                if( !empty($policy['port']) ){
                    $server .= ':'.$policy['port'];
                }
            }else{
                $server = $policy['unix_socket'];            
            }

            if( empty($policy['dirver_options']['ATTR_PERSISTENT']) ){
                $this->mysql = mysql_connect($server, $policy['username'], $policy['password']);
            }else{ //数据库长连接
                $this->mysql = mysql_pconnect($server, $policy['username'], $policy['password']);
            }

            if( !$this->mysql ) {
                throw new RuntimeException('('.__METHOD__.')'.
                    'MySQL Connect Error: #'.$this->errorCode().', '.$this->errorInfo());
            }else{
                if( !empty($policy['dbname']) ){
                    $this->exec( 'USE '.$policy['dbname'] );
                }//END select db

                if( !empty($policy['charset']) ){
                    $charset = 'SET NAMES '.$policy['charset'];
                    if( !empty($policy['collate']) ){
                        $charset .= ' COLLATE '.$policy['collate'];
                    }
                    $this->exec( $charset );
                }//END set charset
            }
        }
    }//END func __construct

    public function __destruct(){
        if( is_resource($this->mysql) ){
            mysql_close($this->mysql);
        }
    }
    
    /**
     * 错误代码
     *
     * @return mixed
     */
    public function errorCode(){
        return mysql_errno();
    }

    /** 
     * 错误性息
     *
     * @return array
     */
    public function errorInfo(){
        return mysql_error();
    }

    /**
     * 执行SQL语句
     *
     * @param string $statement
     *
     * @return int
     */
    public function exec($statement){
        if( mysql_query($statement, $this->mysql) ){
            ++ $this->query_count;
            return TRUE;
        }else{
            throw new RuntimeException('('.__METHOD__.')'.
                'SQL execute Error: #'.$this->errorCode().', '.$this->errorInfo() );
            return FALSE;
        }
    }

    /**
     * 执行SQL语句,返回结果集
     *
     * @param string $statement
     *
     * @return MagicStatement
     */
    public function query($statement){
        if( $stmt = mysql_query($statement, $this->mysql) ){
            ++ $this->query_count;
            return new _mysqlStatement($this->mysql,$stmt); 
        }else{
            throw new RuntimeException('('.__METHOD__.')'.
                'SQL execute Error: #'.$this->errorCode().', '.$this->errorInfo() );
            return FALSE;
        }
    }
    
    /**
     * 预执行SQL语句
     *
     * @param string $statement
     *
     * @return _mysqlStatement
     */
    public function prepare($statement){
        return new _mysqlStatement($this->mysql, null, $statement);
    }

    /**
     * 得到最近一次insert的ID
     *
     * @return string
     */
    public function lastInsertId(){
        return mysql_insert_id($this->mysql);
    }
    
    /**
     * 去除SQL语句中不合法的字符
     *
     * @param string $string
     *
     * @return string
     */
    public function quote($string){
        return '\''.mysql_real_escape_string($string, $this->mysql).'\'';
    }

    /**
     * 开始事务
     */
    public function beginTransaction(){
        $this->exec('START TRANSACTION');
    }

    /**
     * 提交事务
     */
    public function commit(){
        $this->exec('COMMIT');
    }

    /**
     * 回滚事务
     */
    public function rollBack(){
        $this->exec('ROLLBACK');
    }

}//END interface MagicDB

/**
 * MagicDB 结果集
 */
class _mysqlStatement extends SQL_Prepare{

    //首先实现两个抽象方法
    protected function escape($string){
        return '\''.mysql_real_escape_string($string, $this->db).'\'';
    }
    protected function query($sql){
        if( $this->stmt = mysql_query($sql, $this->db) ){
            return TRUE; 
        }else return FALSE;
    }
    public function __destruct(){
        parent::__destruct();
        $this->closeCursor();
    }

    /**
     * 获得单行结果
     *
     * @return mixed
     */
    public function fetch(){
        if( is_resource($this->stmt) ){
            $row = mysql_fetch_assoc($this->stmt);
            if( empty($row) ){
                return FALSE;
            }else return $row;
        }else{
            throw new RuntimeException('('.__METHOD__.')Error: Empty SQL Statement.');
            return FALSE;
        }
    }

    /**
     * 获取所有结果
     *
     * @return array
     */
    public function fetchAll(){
        if( is_resource($this->stmt) ){
            $rows = array();
            while( $row = mysql_fetch_assoc($this->stmt) ){
                $rows[] = $row;
            }
            return $rows;
        }else{
            throw new RuntimeException('('.__METHOD__.')Error: Empty SQL Statement.');
            return FALSE;
        }
    }

    /**
     * 结果计数
     *
     * @return int
     */
    public function rowCount(){
        if( is_resource($this->stmt) ){
            return mysql_num_rows($this->stmt);
        }else return 0;
    }

    /**
     * 下一个结果集
     *
     * @return bool
     */
    public function nextRowset(){
        return $this->closeCursor();
    }

    /**
     * 关闭结果集
     *
     * @return bool
     */
    public function closeCursor(){
        if( is_resource($this->stmt) ){
            return mysql_free_result($this->stmt);
        }else return TRUE;
    }
}//END class mmysqlStatement
?>
